import {
  Body,
  Controller,
  Get,
  Inject,
  Logger,
  Post,
  Req,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { UserService } from '../service/UserService';
import { LoginUserDto } from '../dto/LoginUserDto';
import { R } from 'src/common/R';
import { ClsService } from 'nestjs-cls';
import { Constants } from 'src/common/Constants';
import { UserSession } from 'src/common/UserSession';
import { CacheUtil } from 'src/common/CacheUtil';
import { CacheKey } from 'src/common/CacheKey';
import { ConfigService } from '@nestjs/config';
import SystemConfigService from '../service/SystemConfigService';
import { Request } from 'express';
import LoggerService from '../service/LoggerService';

/*
 * @Author: jingfuu@163.com
 * @Date: 2024-11-08 16:50:25
 * @LastEditTime: 2024-11-27 10:44:10
 * @Description: 认证接口
 */
@ApiTags('认证接口')
@Controller()
export class AuthController {
  private readonly logger = new Logger(AuthController.name);

  @Inject()
  private userService: UserService;

  @Inject()
  private cls: ClsService;

  @Inject()
  private configService: ConfigService;

  @Inject()
  private systemConfigService: SystemConfigService;

  @Inject()
  private loggerService: LoggerService;

  @ApiOperation({ summary: '登录' })
  @Post('/login')
  async userLogin(
    @Body() user: LoginUserDto,
    @Req() req: Request,
  ): Promise<any> {
    const openLogininforFlag =
      await this.systemConfigService.getUserOpenLogininforFlag();
    let token;
    try {
      token = await this.userService.login(user);
      if (openLogininforFlag)
        this.loggerService.loginInfoAdd(user.username, req, '0', '登录成功');
    } catch (error) {
      if (openLogininforFlag)
        this.loggerService.loginInfoAdd(user.username, req, '1', error.message);
      throw error;
    }
    return { code: Constants.SUCCESS, token };
  }

  @ApiOperation({ summary: '获取当前登录用户' })
  @Get('/getInfo')
  async getLoginUserInfo(): Promise<any> {
    const userSession = this.cls.get<UserSession>(Constants.USER_SESSION);
    const { roles, permissions } =
      await this.userService.getUserRoleAndPermissions(userSession.user);
    const { dept, posts } = await this.userService.getUserDeptAndPosts(
      userSession.user,
    );
    //刷新用户session
    userSession.user.roles = roles;
    userSession.user.permissions = permissions;
    userSession.user.dept = dept;
    userSession.user.posts = posts;
    userSession.permissions = permissions;
    userSession.roles = roles.map((role) => role.roleKey);
    CacheUtil.setCacheObject(
      CacheKey.USER_SESSION + userSession.user.userId,
      JSON.stringify(userSession),
      3600 * (await this.systemConfigService.getUserSessionEffectiveTime()),
    );
    const res = {
      code: Constants.SUCCESS,
      user: userSession.user,
      permissions: permissions,
      roles: roles,
    };
    return res;
  }

  @ApiOperation({ summary: '退出登录' })
  @Post('/logout')
  async logout(@Req() req: Request): Promise<R<any>> {
    await this.userService.logout(req);
    return R.ok();
  }

  @ApiOperation({ summary: '获取当前登录用户所有路由' })
  @Get('/getRouters')
  async getRoutes(): Promise<R<any>> {
    const userSession = this.cls.get<UserSession>(Constants.USER_SESSION);
    return R.ok(
      await this.userService.getRouters(
        userSession.user.roles.map((role) => role.roleId),
      ),
    );
  }
}
